package components {

import core.AGameObject;
import core.Facade;

import events.DigComponentEvent;

import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.geom.Rectangle;



public class DigComponent extends AGameObject {

    private var _mouse_block:Sprite;
    private var _fog:Bitmap;
    private var _fogMask:Bitmap;

    private var _cells:Array;
    private var _size:Object;

    private var _cell_size:int = 18;

    private var point_x:int;
    private var point_y:int;
    private var old_point_x:int;
    private var old_point_y:int;

    private var _block_activity:Sprite;
    private var _blocked:Boolean = false;

    public function DigComponent(config:DigLevel) {


        var bitmap:Bitmap = Facade.RESOURCE_MANAGER.getResourceByName("dig_map") as Bitmap;

        _size = new Object();


        _size.x = int(config.size_x);
        _size.y = int(config.size_y);

        _cells = fillArea(_size);
//        _cells = config.cells;


        addChild(bitmap);

        _fog = new Bitmap();
        var _fogBitmapData:BitmapData = new BitmapData(_size.x * _cell_size, _size.y * _cell_size, true, 0xFF000000);
        _fog.bitmapData = _fogBitmapData;
        _fog.alpha = 0.8;
        _fog.cacheAsBitmap = true;
        _fogMask = new Bitmap();
        _fogMask.cacheAsBitmap = true;
        var fogMaskBitmap:BitmapData = new BitmapData(_size.x * _cell_size, _size.y * _cell_size, true, 0xff555555);
        _fogMask.bitmapData = fogMaskBitmap;

        _fog.mask = _fogMask;

        addChild(_fogMask);
        addChild(_fog);
        _mouse_block = new Sprite();
        _mouse_block.graphics.beginFill(0xff0000, 0.3);
        _mouse_block.graphics.drawRect(0, 0, _cell_size, _cell_size);
        _mouse_block.graphics.endFill();

        addChild(_mouse_block);
        var _grid:Sprite = makeGrid(_size);
        addChild(_grid);


        _block_activity = new Sprite();
        _block_activity.graphics.beginFill(0x000000, 0.3);
        _block_activity.graphics.drawRect(0, 0, _size.x * _cell_size, _size.y * _cell_size);
        _block_activity.graphics.endFill();

        addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
        addEventListener(MouseEvent.CLICK, onClick);
        refreshFields(config.cells);
    }

    public function restart():void {
        var fogMaskBitmap:BitmapData = new BitmapData(_size.x * _cell_size, _size.y * _cell_size, true, 0xff555555);
        _fogMask.bitmapData = fogMaskBitmap;
        _cells = fillArea(_size);
    }

    public function block():void {
        if (!_blocked) {
            addChild(_block_activity);
            _blocked = true;
        }

    }

    public function unblock():void {
        if (_blocked) {
            removeChild(_block_activity);
            _blocked = false;
        }

    }

    private function onClick(event:MouseEvent):void {
        if (_cells[point_x][point_y] == 0) {
            dispatchEvent(new DigComponentEvent(point_x, point_y));
        }
    }


    // TODO: add situation with MouseLeave
    private function onMouseMove(event:MouseEvent):void {
        if (event.target != event.currentTarget) return;
        point_x = int(event.localX / _cell_size);
        point_y = int(event.localY / _cell_size);

        if ((point_x>=_size.x) ||(point_y>=_size.y)) return;

        if ((point_x != old_point_x) || (point_y != old_point_y)) {
            if (_cells[point_x][point_y] == 0) {
                _mouse_block.visible = true;
                _mouse_block.x = point_x * _cell_size;
                _mouse_block.y = point_y * _cell_size;
            } else {
                _mouse_block.visible = false;
            }


            old_point_x = point_x;
            old_point_y = point_y;
        }
    }


    private function fillArea(size:Object):Array {
        var _width:int = size.x;
        var _height:int = size.y;
        var res:Array = new Array(_width);
        for (var i:int = 0; i < _width; i++) {
            res[i] = (new Array(_height));
            for (var j:int = 0; j < _height; j++) {
                res[i][j] = 0;
            }
        }
        return res;
    }


    public function refreshFields(field:Array):void {
        var i:int;
        var j:int;
        var rect:Rectangle = new Rectangle();
        rect.width = _cell_size;
        rect.height = _cell_size;
        for (i = 0; i < _size.x; i++) {
            for (j = 0; j < _size.y; j++) {
                if ((field[i][j] == 1) && (_cells[i][j] != field[i][j])) {
                    _cells[i][j] = field[i][j];
                    rect.x = i * _cell_size;
                    rect.y = j * _cell_size;
                    _fogMask.bitmapData.fillRect(rect, 0x00);

                }
            }
        }
    }

    override public function destroy():void {
        removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
        removeEventListener(MouseEvent.CLICK, onClick);
        _mouse_block = null;
        _fog = null;
        _fogMask = null;

        _cells.length = 0;
        _cells = null;

        _block_activity = null;
    }


    private function makeGrid(p_size:Object):Sprite {
        var _width:int = int(p_size.x);
        var _height:int = int(p_size.y);
        var res:Sprite = new Sprite();
        res.graphics.lineStyle(1, 0xffffff, 0.3);
        for (var i:int = 0; i < _width; i++) {
            res.graphics.moveTo((i + 1) * _cell_size, 0);
            res.graphics.lineTo((i + 1) * _cell_size, _height * _cell_size);
        }
        for (i = 0; i < _height; i++) {
            res.graphics.moveTo(0, (i + 1) * _cell_size);
            res.graphics.lineTo(_width * _cell_size, (i + 1) * _cell_size);
        }

        return res;
    }
}
}
